import 'dart:async';

import 'package:custom_pop_up_menu/custom_pop_up_menu.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter_easyloading/flutter_easyloading.dart';
import 'package:flutter_reactive_ble/flutter_reactive_ble.dart';
import 'package:get/get.dart';
import 'package:mziot/app/config/design.dart';
import 'package:mziot/app/data/device_group_entity.dart';
import 'package:mziot/app/data/device_list_entity.dart';
import 'package:mziot/app/modules/devices/device_provider.dart';
import 'package:mziot/app/modules/home/views/insert_view.dart';
import 'package:mziot/app/modules/tabbar/controllers/tabbar_controller.dart';
import 'package:mziot/app/routes/app_pages.dart';
import 'package:mziot/app/tools/blue_service.dart';
import 'package:mziot/app/tools/tools.dart';
import 'package:mziot/generated/locales.g.dart';
import 'package:pull_to_refresh/pull_to_refresh.dart';

class HomeController extends GetxController with StateMixin<List<DeviceListList>> {
  DeviceProvider provider = DeviceProvider();
  RxBool isGroup = false.obs;
  RxInt deviceIndex = 0.obs;
  OverlayEntry? overlayEntryLoader;
  RefreshController refreshController = RefreshController();
  CustomPopupMenuController menuController = CustomPopupMenuController();
  var page = 0;
  int? groupId;
  var groupDeviceList = <DeviceListList>[].obs;
  var hasMore = true;
  var deviceList = <DeviceListList>[].obs;
  var allDevices = <DeviceListList>[].obs;
  var groupList = <DeviceGroupList>[].obs;
  final isLoading = true.obs;
  Timer? _timer;
  var isAction = 0;
  var deleteId = '';
  ScrollController scrollController = ScrollController();
  var isOpen = false.obs;
  var isConnected = false.obs;

  @override
  void onInit() {
    super.onInit();

    isLoading.value = true;
    fetchDevices();
  }

  @override
  void onReady() {
    _timer = Timer.periodic(Duration(seconds: 5), (timer) async {
      isOpen.value = BlueService.share.blueIsOpen;
      isConnected.value = BlueService.share.deviceState == DeviceConnectionState.connected;
      if (isAction < 1) {
        isAction++;
        return;
      }
      deviceList.value = BlueService.share.deviceList;
      if (BlueService.share.deviceState == DeviceConnectionState.disconnected &&
          BlueService.share.blueIsOpen &&
          !BlueService.share.isAll &&
          !BlueService.share.isScaning.value) {
        BlueService.share.scanDevices();
      } else if (BlueService.share.deviceState == DeviceConnectionState.connected) {
        // BlueService.share.takeWrite();
        debugPrint('currentDevice.name ${BlueService.share.currentDevice?.name}');
      }
    });
    super.onReady();
  }

  void refreshAction() {
    BlueService.share.isAll = false;
    page = 0;
    if (isGroup.value) {
      fetchGroup();
    } else {
      fetchDevices();
    }
  }

  void loadMore() {
    if (!hasMore) {
      refreshController.loadNoData();
      return;
    }
    page += 1;
    if (isGroup.value) {
      fetchGroup();
    } else {
      fetchDevices();
    }
  }

  void fetchDevices() {
    var type = 1;
    if (deviceIndex.value == 1) {
      type = 3;
    } else if (deviceIndex.value == 2) {
      type = 2;
    }
    if (deviceList.isEmpty) {
      EasyLoading.show();
      isLoading.value = true;
    }
    provider.takeDeviceList(type, page).then((value) {
      if (value?.isSuccess ?? false) {
        final values = value?.data?.list ?? [];
        if (page == 0) {
          deviceList.value = values;
          refreshController.refreshCompleted();
        } else {
          deviceList.value.addAll(values);
        }
        deviceList.forEach((element) {
          element.lightRate.value = element.deviceLightRate ?? 0;
          element.closeState.value = element.isClose ?? true;
          element.isWifi.value = element.connectStatus == 1 ? true : false;
          element.isLock.value = element.lockStatus ?? false;
        });
        if (BlueService.share.deviceState == DeviceConnectionState.connected) {
          deviceList.value.forEach((element) {
            final index = BlueService.share.localDevices
                .indexWhere((delement) => delement.nodeId == element.deviceSerialnum);
            if (index >= 0) {
              element.isBluetooth.value =
                  BlueService.share.localDevices[index].isBluetooth ?? false;
              element.closeState.value =
                  BlueService.share.localDevices[index].turnState == 1 ? false : true;
              element.lightRate.value = BlueService.share.localDevices[index].lighting ?? 0;
              element.isWifi.value =
                  BlueService.share.localDevices[index].isWifi == 1 ? true : false;
            }
          });
        }
        BlueService.share.deviceList = deviceList.value;
        hasMore = value?.data?.hasNext ?? true;
        if (!hasMore) {
          refreshController.loadNoData();
        } else {
          refreshController.loadComplete();
        }
      } else {
        refreshController.refreshCompleted();
        refreshController.loadComplete();
      }
    }).whenComplete(() {
      isLoading.value = false;
      EasyLoading.dismiss();
    });
  }

  void fetchGroup() {
    if (groupList.isEmpty) {
      isLoading.value = true;
      EasyLoading.show();
    }
    provider.takeGroupList(page).then((value) {
      if (value?.isSuccess ?? false) {
        final values = value?.data?.list ?? [];
        if (page == 0) {
          groupList.value = values;
          refreshController.refreshCompleted();
        } else {
          groupList.value.addAll(values);
        }
        hasMore = value?.data?.hasNext ?? true;
        groupList.forEach((element) {
          element.closeState.value = element.isClose ?? true;
          element.isEmpty.value = (element.deviceNum ?? 0) == 0 ? true : false;
          element.isLock.value = element.lockStatus ?? false;
        });
        if (!hasMore) {
          refreshController.loadNoData();
        } else {
          refreshController.loadComplete();
        }
      } else {
        refreshController.refreshCompleted();
        refreshController.loadComplete();
      }
    }).whenComplete(() {
      isLoading.value = false;
      EasyLoading.dismiss();
    });
  }

  void fetchGroupDevices() {
    if (groupDeviceList.isEmpty) {
      EasyLoading.show();
    }
    provider.takeGroupDevices(groupId!).then((value) {
      if (value.isSuccess) {
        groupDeviceList.value = value.data?.list ?? [];
        groupDeviceList.value.forEach((element) {
          element.lightRate.value = element.deviceLightRate ?? 0;
          element.closeState.value = element.isClose ?? true;
          element.isWifi.value = element.connectStatus == 1 ? true : false;
          element.isLock.value = element.lockStatus ?? false;
        });
        if (BlueService.share.deviceState == DeviceConnectionState.connected) {
          groupDeviceList.value.forEach((element) {
            final index = BlueService.share.localDevices
                .indexWhere((delement) => delement.nodeId == element.deviceSerialnum);
            if (index >= 0) {
              element.isBluetooth.value =
                  BlueService.share.localDevices[index].isBluetooth ?? false;
              element.closeState.value =
                  BlueService.share.localDevices[index].turnState == 1 ? false : true;
              element.lightRate.value = BlueService.share.localDevices[index].lighting ?? 0;
              element.isWifi.value =
                  BlueService.share.localDevices[index].isWifi == 1 ? true : false;
            }
          });
        }
      }
    }).whenComplete(() {
      EasyLoading.dismiss();
    });
  }

  void fetchAllDevices() {
    provider.takeDevices(groupId!).then((value) {
      if (value.isSuccess) {
        allDevices.value = value.data ?? [];
        if (allDevices.value.isEmpty) {
          showToast(LocaleKeys.home_device_empty.tr);
          return;
        }
        Get.generalDialog(pageBuilder: (ctx, a1, a2) {
          return InsertView(allDevices, (value) {
            final deviceIds = value.map((e) => e.deviceId!).toList();
            fetchAddGroup(deviceIds);
          });
        });
      } else {
        showToast(value.msg ?? '');
      }
    }).whenComplete(() {
      EasyLoading.dismiss();
    });
  }

  void fetchAddGroup(List<int> deviceIds) {
    provider.addGroup(groupId!, deviceIds).then((value) {
      if (value.isSuccess) {
        fetchGroupDevices();
        BlueService.share.execCmds(value.data);
      } else {
        showToast(value.msg ?? '');
      }
    });
  }

  void fetchDeleteDevice(int id) async {
    EasyLoading.show();
    provider.deleteDevice([id]).then((value) {
      if (value.isSuccess) {
        overlayEntryLoader?.remove();
        Get.back();
        if (groupId != null) {
          List<DeviceListList> list = groupDeviceList.value;
          final index = list.indexWhere((element) => element.id == id);
          list.removeAt(index);
          groupDeviceList.value = [];
          groupDeviceList.value = list;
        } else {
          List<DeviceListList> list = deviceList.value;
          final index = list.indexWhere((element) => element.id == id);
          final itemModel = list[index];
          list.removeAt(index);
          final isContain = BlueService.share.deleteIds.contains(itemModel.deviceSerialnum ?? '');
          if (!isContain && itemModel.deviceSerialnum != null) {
            BlueService.share.deleteIds.add(itemModel.deviceSerialnum!);
          }
          deleteId = itemModel.deviceSerialnum ?? '';
          deviceList.value = [];
          deviceList.value = list;
          BlueService.share.deviceList = list;
          var devices = BlueService.share.localDevices;
          final index1 =
              devices.indexWhere((element) => element.nodeId == itemModel.deviceSerialnum);
          if (index1 >= 0) {
            devices.removeAt(index1);
            BlueService.share.localDevices = devices;
          }
        }
        if (groupId != null) {
          fetchGroupDevices();
        } else {
          fetchDevices();
        }
        BlueService.share.execCmds(value.data);
        final name = BlueService.share.currentDevice?.name.split('_').last;
        if (deleteId == name) {
          BlueService.share.localDevices.forEach((element) {
            element.isBluetooth = false;
          });
          if (groupId != null) {
            groupDeviceList.forEach((element) {
              element.isBluetooth.value = false;
            });
          } else {
            deviceList.forEach((element) {
              element.isBluetooth.value = false;
            });
          }
        }
      }
      showToast(value.msg ?? '');
    }).whenComplete(() {
      EasyLoading.dismiss();
    });
  }

  void fetchDeleteGroup(int id) {
    EasyLoading.show();
    provider.deleteGroup([id]).then((value) {
      if (value.isSuccess) {
        List<DeviceGroupList> list = groupList.value;
        list.removeWhere((element) => element.id == id);
        groupList.value = [];
        groupList.value = list;
      }
      showToast(value.msg ?? '');
    }).whenComplete(() {
      EasyLoading.dismiss();
    });
  }

  void fetchLeaveGroup(int id) {
    EasyLoading.show();
    provider.leaveGroup(groupId!, id).then((value) {
      if (value.isSuccess) {
        List<DeviceListList> list = groupDeviceList.value;
        list.removeWhere((element) => element.id == id);
        groupDeviceList.value = [];
        groupDeviceList.value = list;
        BlueService.share.execCmds(value.data);
      }
      showToast(value.msg ?? '');
    }).whenComplete(() {
      EasyLoading.dismiss();
    });
  }

  void fetchSwitchDevices(int index, bool isList,
      {DeviceListList? device, DeviceGroupList? group}) {
    var close = false;
    if (device != null) {
      close = device.closeState.value;
    } else {
      close = (group?.closeState.value ?? false);
    }
    EasyLoading.show();
    provider
        .switchDevices(
      isClose: !close,
      id: device?.id,
      groupId: group?.id,
    )
        .then((value) {
      if (value.isSuccess) {
        if (group != null) {
          groupList[index].closeState.value = !groupList[index].closeState.value;
        } else {
          if (isList) {
            groupDeviceList.value[index].closeState.value =
                !groupDeviceList.value[index].closeState.value;
          } else {
            deviceList.value[index].closeState.value = !deviceList.value[index].closeState.value;
          }
        }
        BlueService.share.execCmds(value.data);
        isAction = 0;
      }
      showToast(value.msg ?? '');
    }).whenComplete(() {
      EasyLoading.dismiss();
    });
  }

  //去灯光调节
  void toLighting(int index) async {
    logger.v('isGroup.value ${isGroup.value}');
    final type = await Get.toNamed(
      Routes.LIGHTING,
      arguments: groupId != null
          ? groupDeviceList[index]
          : isGroup.value
              ? groupList[index]
              : deviceList[index],
    );
    if (type == 'group') {
      isGroup.value = true;
    } else if (type == 'scene') {
      if (groupId != null) {
        groupId = null;
        Get.back();
      }
      Get.find<TabbarController>().index.value = 1;
    }
    if (groupId != null) {
      fetchGroupDevices();
    } else {
      refreshAction();
    }
  }

  //未连接蓝牙和网络提示
  void deleteAlert(int id) {
    Get.generalDialog(pageBuilder: (ctx, a, s) {
      return CupertinoAlertDialog(
        content: Text(
          LocaleKeys.home_delete_device.tr,
          style: MFont.semi_Bold17.apply(color: MColor.xFF333333),
        ),
        actions: <Widget>[
          TextButton(
            onPressed: () {
              Get.back();
            },
            child: Text(
              LocaleKeys.home_no.tr,
              style: MFont.regular17.apply(color: MColor.xFF333333),
            ),
          ),
          TextButton(
            onPressed: () {
              fetchDeleteDevice(id);
            },
            child: Text(
              LocaleKeys.home_yes.tr,
              style: MFont.semi_Bold17.apply(color: MColor.xFF333333),
            ),
          ),
        ],
      );
    });
  }

  //删除确认
  void deleteConfirm(int? id) {
    Get.generalDialog(pageBuilder: (ctx, a, s) {
      var message = "";
      if (isGroup.value && groupId == null) {
        message = LocaleKeys.home_delete_group.tr;
      } else if (isGroup.value) {
        message = LocaleKeys.home_leave_group.tr;
      } else {
        message = LocaleKeys.home_delete_devices.tr;
      }
      return CupertinoAlertDialog(
        content: Text(
          message,
          style: MFont.semi_Bold17.apply(color: MColor.xFF333333),
        ),
        actions: <Widget>[
          TextButton(
            onPressed: () {
              Get.back();
            },
            child: Text(
              LocaleKeys.home_no.tr,
              style: MFont.regular17.apply(color: MColor.xFF333333),
            ),
          ),
          TextButton(
            onPressed: () {
              Get.back();
              if (isGroup.value && groupId == null) {
                fetchDeleteGroup(id!);
              } else if (isGroup.value) {
                fetchLeaveGroup(id!);
              } else {
                fetchDeleteDevice(id!);
              }
            },
            child: Text(
              LocaleKeys.home_yes.tr,
              style: MFont.semi_Bold17.apply(color: MColor.xFF333333),
            ),
          ),
        ],
      );
    });
  }

  @override
  void onClose() {}

  @override
  void dispose() {
    // TODO: implement dispose
    refreshController.dispose();
    menuController.dispose();
    scrollController.dispose();
    _timer?.cancel();
    super.dispose();
  }
}
